/**
 * www.easyplatform.cn ©2016
 */
package cn.easyplatform.studio.web.editors.entity;

import cn.easyplatform.entities.BaseEntity;
import cn.easyplatform.entities.EntityInfo;
import cn.easyplatform.entities.beans.task.DecisionBean;
import cn.easyplatform.entities.beans.task.TaskBean;
import cn.easyplatform.entities.beans.task.TransitionBean;
import cn.easyplatform.entities.beans.task.Variable;
import cn.easyplatform.entities.helper.EventLogic;
import cn.easyplatform.lang.Nums;
import cn.easyplatform.lang.Strings;
import cn.easyplatform.studio.StudioApp;
import cn.easyplatform.studio.cmd.entity.GetAndLockEntityCmd;
import cn.easyplatform.studio.cmd.entity.GetBaseEntityListCmd;
import cn.easyplatform.studio.cmd.entity.GetEntityCmd;
import cn.easyplatform.studio.cmd.entity.SaveCmd;
import cn.easyplatform.studio.cmd.identity.GetAccessInfoCmd;
import cn.easyplatform.studio.cmd.link.*;
import cn.easyplatform.studio.cmd.taskLink.*;
import cn.easyplatform.studio.context.Contexts;
import cn.easyplatform.studio.utils.*;
import cn.easyplatform.studio.vos.*;
import cn.easyplatform.studio.web.action.CreateAction;
import cn.easyplatform.studio.web.editors.*;
import cn.easyplatform.studio.web.layout.WorkbenchController;
import cn.easyplatform.studio.web.views.impl.AbstractView;
import cn.easyplatform.studio.web.views.impl.EntityView;
import cn.easyplatform.type.EntityType;
import cn.easyplatform.type.FieldType;
import cn.easyplatform.type.ScopeType;
import cn.easyplatform.type.SubType;
import cn.easyplatform.web.ext.cmez.CMeditor;
import cn.easyplatform.web.ext.jm.Mind;
import cn.easyplatform.web.ext.jm.Node;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.zkoss.util.resource.Labels;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.*;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zkmax.zul.Chosenbox;
import org.zkoss.zkmax.zul.Orgitem;
import org.zkoss.zul.*;
import org.zkoss.zul.Button;
import org.zkoss.zul.Label;

import java.util.*;

/**
 * @author <a href="mailto:shiny_vc@163.com">陈云亮</a> <br/>
 * @since 2.0.0 <br/>
 */
public class TaskEntityEditor extends AbstractEntityEditor<TaskBean> implements CodeEditor {
    private final static Logger logger = LoggerFactory.getLogger(TaskEntityEditor.class);

    private enum LanguageType {
        Language_En, Language_Ch
    }
    private Tabbox tabbox;

    //private Organigram ecotree;

    private Mind ecoMind;

    private CMeditor decision;

    private Grid variables;

    private Grid transitions;

    private Textbox entityId;

    private Textbox entityName;

    private Textbox entityDesp;

    private Bandbox entityRef;

    private Bandbox entityTable;

    private Bandbox entityInherit;

    private Bandbox entityIcon;

    private Combobox entityCode;

    private Combobox entityType;

    private Checkbox entityUpdateable;

    private Checkbox entityVisible;

    private Bandbox onInit;

    private Bandbox onClose;

    private Bandbox onPreCommit;

    private Bandbox onPreCommitRollback;

    private Bandbox onBeforeCommit;

    private Bandbox onAfterCommit;

    private Bandbox onRollback;

    private Bandbox onCommitted;

    private Bandbox onCommittedRollback;

    private Menupopup relationMenupopup;

    private Menuitem appendVirtualItem;

    private Menuitem appendEntityItem;

    private Menuitem deleteVirtualItem;

    private Menuitem deleteEntityItem;

    private Checkbox mainTaskSwitch;

    private Chosenbox accessChosenbox;

    private Combobox anonymousCombobox;

    private List<AccessVo> accessVos;

    private List<LinkVo> voList;

    private Map<String, LinkVo> linkVoMap;

    private TypeLinkVo typeLinkVo;

    private Boolean isShowCreate = false;

    private LanguageType languageType = LanguageType.Language_Ch;
    /**
     * @param workbench
     * @param entity
     * @param code
     */
    public TaskEntityEditor(WorkbenchController workbench, TaskBean entity,
                            char code) {
        super(workbench, entity, code);
    }

    @Override
    public void create(Object... args) {
        super.create(args);
        Tabpanel tabpanel = new Tabpanel();
        Idspace is = new Idspace();
        is.setHflex("1");
        is.setVflex("1");
        is.setParent(tabpanel);
        Executions.createComponents("~./include/editor/entity/task.zul", is,
                null);
        String theme = Contexts.getUser().getEditorTheme();
        accessVos = StudioApp.execute(new GetAccessInfoCmd());
        for (Component comp : is.getFellows()) {
            if (comp.getId().equals("entityTask_tabbox_main")) {
                tabbox = (Tabbox) comp;
                comp.addEventListener(Events.ON_SELECT, this);
            }/* else if (comp.getId().equals("entityTask_organigram_tree")) {
                ecotree = (Organigram) comp;
                ecotree.addEventListener(Events.ON_SELECT, this);
            } */else if (comp.getId().equals("entityTask_grid_flow_transitions")) {
                transitions = (Grid) comp;
            } else if (comp.getId().equals("entityTask_cmeditor_flow_decision")) {
                decision = (CMeditor) comp;
                decision.setTheme(theme);
                decision.addEventListener(Events.ON_CHANGE, this);
            } else if (comp.getId().equals("entityTask_grid_variable")) {
                variables = (Grid) comp;
            } else if (comp.getId().equals("entityTask_cmeditor_entityTask_tabpanel_code")) {
                source = (CMeditor) comp;
                source.setTheme(theme);
            } else if (comp.getId().equals("entityTask_textbox_property_id")) {
                entityId = (Textbox) comp;
                entityId.setValue(entity.getId());
                entityId.setReadonly(true);
            } else if (comp.getId().equals("entityTask_textbox_property_name")) {
                entityName = (Textbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                entityName.setValue(entity.getName());
            } else if (comp.getId().equals("entityTask_textbox_property_desp")) {
                entityDesp = (Textbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                entityDesp.setValue(entity.getDescription());
            } else if (comp.getId().equals("entityTask_bandbox_property_ref")) {
                entityRef = (Bandbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                comp.addEventListener(Events.ON_OPEN, this);
                comp.addEventListener(Events.ON_OK, this);
                comp.getNextSibling().addEventListener(Events.ON_CLICK, this);
                entityRef.setValue(entity.getRefId());
            } else if (comp.getId().equals("entityTask_bandbox_property_table")) {
                entityTable = (Bandbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                comp.addEventListener(Events.ON_OPEN, this);
                comp.addEventListener(Events.ON_OK, this);
                comp.getNextSibling().addEventListener(Events.ON_CLICK, this);
                entityTable.setValue(entity.getTable());
            } else if (comp.getId().equals("entityTask_bandbox_property_inherit")) {
                entityInherit = (Bandbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                comp.addEventListener(Events.ON_OPEN, this);
                comp.addEventListener(Events.ON_OK, this);
                entityInherit.setValue(entity.getInheritId());
            } else if (comp.getId().equals("entityTask_bandbox_property_icon")) {
                entityIcon = (Bandbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                comp.addEventListener(Events.ON_OPEN, this);
                comp.addEventListener(Events.ON_OK, this);
                entityIcon.setValue(entity.getImage());
            } else if (comp.getId().equals("entityTask_combobox_property_code")) {
                entityCode = (Combobox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                if (entity.getProcessCode().equals("C"))
                    entityCode.setSelectedIndex(0);
                else if (entity.getProcessCode().equals("R"))
                    entityCode.setSelectedIndex(1);
                else if (entity.getProcessCode().equals("U"))
                    entityCode.setSelectedIndex(2);
                else
                    entityCode.setSelectedIndex(3);
            } else if (comp.getId().equals("entityTask_combobox_property_type")) {
                entityType = (Combobox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                entityType.setSelectedIndex(Nums.toInt(entity.getExecuteType(), 0));
            } else if (comp.getId().equals("entityTask_switchbox_property_updateable")) {
                entityUpdateable = (Checkbox) comp;
                comp.addEventListener(Events.ON_CHECK, this);
                entityUpdateable.setChecked(entity.isUpdatable());
            } else if (comp.getId().equals("entityTask_switchbox_property_visible")) {
                entityVisible = (Checkbox) comp;
                comp.addEventListener(Events.ON_CHECK, this);
                entityVisible.setChecked(entity.isVisible());
            } else if (comp.getId().equals("entityTask_combobox_property_anonymity")) {
                anonymousCombobox = (Combobox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                anonymousCombobox.setSelectedIndex(Nums.toInt(entity.getAccessType(), 0));
            } else if (comp.getId().equals("entityTask_bandbox_event_onInit")) {
                onInit = (Bandbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                comp.addEventListener(Events.ON_OPEN, this);
                comp.getNextSibling().addEventListener(Events.ON_CLICK, this);
                if (entity.getOnInit() != null) {
                    if (!Strings.isBlank(entity.getOnInit().getId())) {
                        onInit.setValue(entity.getOnInit().getId());
                    } else if (!Strings
                            .isBlank(entity.getOnInit().getContent())) {
                        ((Button) onInit.getNextSibling())
                                .setSclass("epeditor-btn-mark");
                    }
                }
            } else if (comp.getId().equals("entityTask_bandbox_event_onClose")) {
                onClose = (Bandbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                comp.addEventListener(Events.ON_OPEN, this);
                comp.getNextSibling().addEventListener(Events.ON_CLICK, this);
                if (entity.getOnClose() != null) {
                    if (!Strings.isBlank(entity.getOnClose().getId())) {
                        onClose.setValue(entity.getOnClose().getId());
                    } else if (!Strings.isBlank(entity.getOnClose()
                            .getContent())) {
                        ((Button) onClose.getNextSibling())
                                .setSclass("epeditor-btn-mark");
                    }
                }
            } else if (comp.getId().equals("entityTask_bandbox_event_onPreCommit")) {
                onPreCommit = (Bandbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                comp.addEventListener(Events.ON_OPEN, this);
                comp.getNextSibling().addEventListener(Events.ON_CLICK, this);
                if (entity.getOnPreCommit() != null) {
                    if (!Strings.isBlank(entity.getOnPreCommit().getId())) {
                        onPreCommit.setValue(entity.getOnPreCommit().getId());
                    } else if (!Strings.isBlank(entity.getOnPreCommit()
                            .getContent())) {
                        ((Button) onPreCommit.getNextSibling())
                                .setSclass("epeditor-btn-mark");
                    }
                }
            } else if (comp.getId().equals("entityTask_bandbox_event_onPreCommitRollback")) {
                onPreCommitRollback = (Bandbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                comp.addEventListener(Events.ON_OPEN, this);
                comp.getNextSibling().addEventListener(Events.ON_CLICK, this);
                if (entity.getOnPreCommitRollback() != null) {
                    if (!Strings.isBlank(entity.getOnPreCommitRollback()
                            .getId())) {
                        onPreCommitRollback.setValue(entity
                                .getOnPreCommitRollback().getId());
                    } else if (!Strings.isBlank(entity.getOnPreCommitRollback()
                            .getContent())) {
                        ((Button) onPreCommitRollback.getNextSibling())
                                .setSclass("epeditor-btn-mark");
                    }
                }
            } else if (comp.getId().equals("entityTask_bandbox_event_onBeforeCommit")) {
                onBeforeCommit = (Bandbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                comp.addEventListener(Events.ON_OPEN, this);
                comp.getNextSibling().addEventListener(Events.ON_CLICK, this);
                if (entity.getOnBeforeCommit() != null) {
                    if (!Strings.isBlank(entity.getOnBeforeCommit().getId())) {
                        onBeforeCommit.setValue(entity.getOnBeforeCommit()
                                .getId());
                    } else if (!Strings.isBlank(entity.getOnBeforeCommit()
                            .getContent())) {
                        ((Button) onBeforeCommit.getNextSibling())
                                .setSclass("epeditor-btn-mark");
                    }
                }
            } else if (comp.getId().equals("entityTask_bandbox_event_onAfterCommit")) {
                onAfterCommit = (Bandbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                comp.addEventListener(Events.ON_OPEN, this);
                comp.getNextSibling().addEventListener(Events.ON_CLICK, this);
                if (entity.getOnAfterCommit() != null) {
                    if (!Strings.isBlank(entity.getOnAfterCommit().getId())) {
                        onAfterCommit.setValue(entity.getOnAfterCommit()
                                .getId());
                    } else if (!Strings.isBlank(entity.getOnAfterCommit()
                            .getContent())) {
                        ((Button) onAfterCommit.getNextSibling())
                                .setSclass("epeditor-btn-mark");
                    }
                }
            } else if (comp.getId().equals("entityTask_bandbox_event_onRollback")) {
                onRollback = (Bandbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                comp.addEventListener(Events.ON_OPEN, this);
                comp.getNextSibling().addEventListener(Events.ON_CLICK, this);
                if (entity.getOnRollback() != null) {
                    if (!Strings.isBlank(entity.getOnRollback().getId())) {
                        onRollback.setValue(entity.getOnRollback().getId());
                    } else if (!Strings.isBlank(entity.getOnRollback()
                            .getContent())) {
                        ((Button) onRollback.getNextSibling())
                                .setSclass("epeditor-btn-mark");
                    }
                }
            } else if (comp.getId().equals("entityTask_bandbox_event_onCommitted")) {
                onCommitted = (Bandbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                comp.addEventListener(Events.ON_OPEN, this);
                comp.getNextSibling().addEventListener(Events.ON_CLICK, this);
                if (entity.getOnCommitted() != null) {
                    if (!Strings.isBlank(entity.getOnCommitted().getId())) {
                        onCommitted.setValue(entity.getOnCommitted().getId());
                    } else if (!Strings.isBlank(entity.getOnCommitted()
                            .getContent())) {
                        ((Button) onCommitted.getNextSibling())
                                .setSclass("epeditor-btn-mark");
                    }
                }
            } else if (comp.getId().equals("entityTask_bandbox_event_onCommittedRollback")) {
                onCommittedRollback = (Bandbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                comp.addEventListener(Events.ON_OPEN, this);
                comp.getNextSibling().addEventListener(Events.ON_CLICK, this);
                if (entity.getOnCommittedRollback() != null) {
                    if (!Strings.isBlank(entity.getOnCommittedRollback()
                            .getId())) {
                        onCommittedRollback.setValue(entity
                                .getOnCommittedRollback().getId());
                    } else if (!Strings.isBlank(entity.getOnCommittedRollback()
                            .getContent())) {
                        ((Button) onCommittedRollback.getNextSibling())
                                .setSclass("epeditor-btn-mark");
                    }
                }
            } else if (comp.getId().equals("entityTask_tabbox_flow_addTransition")
                    || comp.getId().equals("entityTask_column_variable_addVariable")) {
                comp.addEventListener(Events.ON_CLICK, this);
            } else if ("entityTask_switchbox_property_mainEntity".equals(comp.getId())) {
                mainTaskSwitch = (Checkbox) comp;
                boolean isChecked = entity.getSubType() != null && entity.getSubType().equals(SubType.Main.getName());
                comp.addEventListener(Events.ON_CHECK, this);
                mainTaskSwitch.setChecked(isChecked);
            } else if ("entityTask_menuitem_appendVirtual".equals(comp.getId())) {
                appendVirtualItem = (Menuitem) comp;
                comp.addEventListener(Events.ON_CLICK, this);
            } else if ("entityTask_menuitem_appendEntity".equals(comp.getId())) {
                appendEntityItem = (Menuitem) comp;
                comp.addEventListener(Events.ON_CLICK, this);
            } else if ("entityTask_menuitem_deleteVirtual".equals(comp.getId())) {
                deleteVirtualItem = (Menuitem) comp;
                comp.addEventListener(Events.ON_CLICK, this);
            } else if ("entityTask_menuitem_deleteEntity".equals(comp.getId())) {
                deleteEntityItem = (Menuitem) comp;
                comp.addEventListener(Events.ON_CLICK, this);
            } else if ("settingsTask".equals(comp.getId())) {
                comp.addEventListener(Events.ON_CLICK, this);
            } else if ("entityTask_button_HVSwitch".equals(comp.getId())){
                comp.setAttribute("horizon", false);
                comp.addEventListener(Events.ON_CLICK, this);
            } else if ("entityTask_button_ECSwitch".equals(comp.getId())) {
                comp.setAttribute("chinese", true);
                comp.addEventListener(Events.ON_CLICK, this);
            } else if ("entityTask_button_autoAddLink".equals(comp.getId())) {
                comp.addEventListener(Events.ON_CLICK, this);
            } else if ("entityTask_menupopup_organmenu".equals(comp.getId())) {
                relationMenupopup = (Menupopup) comp;
            } else if ("entityTask_mind_tree".equals(comp.getId())) {
                ecoMind = (Mind) comp;
                ecoMind.addEventListener(Events.ON_DOUBLE_CLICK,this);
                ecoMind.addEventListener(Events.ON_SELECTION, this);
            } else if ("task_label_name".equals(comp.getId())) {
                Label nameLabel = (Label) comp;
                nameLabel.setValue(Labels.getLabel("entity.id") + ":" + entity.getId() + " " +
                        Labels.getLabel("entity.name") + ":" + entity.getName());
            } else if ("entityTask_chosenbox_access".equals(comp.getId())) {
                accessChosenbox = (Chosenbox) comp;
                ListModelList<String> model = new ListModelList<>(accessVos.size());
                List<String> allAccess = new ArrayList<>();
                List<String> access = new ArrayList<>();
                List<String> containAccess = new ArrayList<>();
                if (Strings.isBlank(entity.getAccess()) == false) {
                    access = Arrays.asList(entity.getAccess().split(","));
                }
                for (AccessVo field : accessVos) {
                    StringBuffer code = new StringBuffer(field.getCode());
                    if (Strings.isBlank(field.getControlType()) == false)
                        code.append("_").append(field.getControlType());
                    model.add(code.toString());
                    allAccess.add(code.toString());
                }
                List<String> noAccess = new ArrayList<>();
                if (access.size() > 0) {
                    for (String accessId : access) {
                        if (allAccess.contains(accessId) == false) {
                            noAccess.add(accessId);
                        } else
                            containAccess.add(accessId);
                    }
                }
                if (noAccess.size() > 0) {
                    WebUtils.showInfo(Labels.getLabel("menu.access.lose", new Object[] {noAccess.get(0)}));
                    entity.setAccess(StringUtil.listToString(containAccess, ","));
                    setDirty();
                }
                accessChosenbox.setModel(model);
                accessChosenbox.setSelectedObjects(containAccess);
                comp.addEventListener(Events.ON_SELECT,this);
            }
        }
        voList = StudioApp.execute(ecoMind,new GetLinkCmd(entity.getId()));
        //voList = StudioApp.execute(ecotree,new GetLinkCmd(entity.getId()));
        List<TypeLinkVo> typeLinkVos = StudioApp.execute(new GetTaskLinkCmd(
                new TypeLinkVo(entity.getId(), null, null)));
        if (voList.size() == 0)
        {
            LinkVo rootVo = new LinkVo(entity.getId(), null, entity.getName(), entity.getType(), entity.getSubType(),
                    entity.getDescription(), null, null, null, null, "E");
            StudioApp.execute(new AddLinkCmd(rootVo));
            voList = StudioApp.execute(ecoMind, new GetLinkCmd(entity.getId()));
            //voList = StudioApp.execute(ecotree, new GetLinkCmd(entity.getId()));
        }
        if (typeLinkVos == null || typeLinkVos.size() == 0) {
            boolean isMain = SubType.Main.getName().equals(entity.getSubType());
            StudioApp.execute(new AddTaskLinkCmd(entity.getId(), null, isMain));
            typeLinkVo = StudioApp.execute(new GetTaskLinkCmd(
                    new TypeLinkVo(entity.getId(), null, null))).get(0);
        } else
            typeLinkVo = typeLinkVos.get(0);
        setVariables();
        setDecision();
        redraw();
        workbench.addEditor(tab, tabpanel);
    }

    @Override
    public void insertTodo() {
        decision.insertText("<!-- TODO -->");
    }

    @Override
    public void insertComments() {
        decision.insertText("<!-- This is a comment -->");
    }

    @Override
    public void undo() {
        decision.exeCmd("undo");
    }

    @Override
    public void redo() {
        decision.exeCmd("redo");
    }

    @Override
    public void selectAll() {
        decision.exeCmd("selectAll");
    }

    @Override
    public void format() {
        decision.exeCmd("format");
    }

    @Override
    public void formatAll() {
        decision.exeCmd("formatAll");
    }

    @Override
    public void deleteLine() {
        decision.exeCmd("deleteLine");
    }

    @Override
    public void indentMore() {
        decision.exeCmd("indentMore");
    }

    @Override
    public void indentLess() {
        decision.exeCmd("indentLess");
    }

    @Override
    public void find() {
        decision.exeCmd("find");
    }

    @Override
    public void findNext() {
        decision.exeCmd("findNext");
    }

    @Override
    public void findPrev() {
        decision.exeCmd("findPrev");
    }

    @Override
    public void replace() {
        decision.exeCmd("replace");
    }

    @Override
    public void replaceAll() {
        decision.exeCmd("replaceAll");
    }
    /**
     * 初始化流程
     */
    private void setDecision() {
        if (entity.getDecision() != null) {
            if (!Strings.isBlank(entity.getDecision().getExpr())) {
                decision.setValue(entity.getDecision().getExpr());
            }

            if (entity.getDecision().getTransitions() != null) {
                for (TransitionBean bean : entity.getDecision()
                        .getTransitions())
                    createTransition(bean);
            }
        }
    }

    /**
     * 初始化变量
     */
    private void setVariables() {
        if (entity.getVariables() != null) {
            for (Variable var : entity.getVariables())
                createVariable(var);
        }
    }

    /**
     * 创建流程分支
     *
     * @param bean
     */
    private Group createTransition(TransitionBean bean) {
        Group group = new Group(Labels.getLabel("entity.task.decision.name"));
        // 第一个打开
        group.setOpen(entity.getDecision().getTransitions().size() == 1);
        group.setParent(transitions.getRows());
        Hlayout hlayout = new Hlayout();
        hlayout.setHflex("1");
        Textbox name = new Textbox(bean.getName());
        name.setHflex("1");
        name.setParent(hlayout);
        A a = new A();
        a.setLabel(Labels.getLabel("button.delete"));
        a.setIconSclass("z-icon-times");
        a.setSclass("pull-right");
        a.setParent(hlayout);
        hlayout.setParent(group);

        // displayName
        Row row = new Row();
        Label label = new Label(
                Labels.getLabel("entity.task.decision.displayName"));
        label.setParent(row);
        Textbox displayName = new Textbox(bean.getDisplayName());
        displayName.setHflex("1");
        displayName.setParent(row);
        row.setParent(transitions.getRows());
        // from
        row = new Row();
        label = new Label(Labels.getLabel("entity.task.decision.from"));
        label.setParent(row);
        Textbox from = new Textbox(bean.getFrom());
        from.setHflex("1");
        from.setParent(row);
        row.setParent(transitions.getRows());
        // to
        row = new Row();
        label = new Label(Labels.getLabel("entity.task.decision.to"));
        label.setParent(row);
        Hlayout div = new Hlayout();
        div.setHflex("1");
        Bandbox to = new Bandbox();
        to.setHflex("1");
        to.setValue(bean.getTo());
        to.setParent(div);
        Button btn = new Button();
        btn.setIconSclass("z-icon-edit");
        btn.setSclass("epeditor-btn");
        btn.setStyle("margin-left:4px");
        btn.setParent(div);
        div.setParent(row);
        row.setParent(transitions.getRows());
        // logic
        row = new Row();
        label = new Label(Labels.getLabel("entity.task.decision.logic"));
        label.setParent(row);
        div = new Hlayout();
        div.setHflex("1");
        Bandbox logic = new Bandbox();
        logic.setValue(bean.getLogicId());
        logic.setHflex("1");
        logic.setParent(div);
        btn = new Button();
        btn.setIconSclass("z-icon-edit");
        if (Strings.isBlank(bean.getMappings()))
            btn.setSclass("epeditor-btn");
        else
            btn.setSclass("epeditor-btn-mark");
        btn.setStyle("margin-left:4px");
        btn.setParent(div);
        div.setParent(row);
        row.setParent(transitions.getRows());
        new TransitionObject(bean, name, displayName, from, to, logic);
        return group;
    }

    /**
     * 生成变量
     *
     * @param var
     */
    private void createVariable(Variable var) {
        Row row = new Row();
        row.setValue(var);
        // name
        Textbox name = new Textbox(var.getName());
        name.setHflex("1");
        name.setParent(row);
        // type
        Combobox type = WebUtils.createFieldTypeBox();
        type.setValue(var.getType().name());
        type.setHflex("1");
        type.setParent(row);
        // length
        Intbox length = new Intbox(var.getLength());
        length.setHflex("1");
        length.setParent(row);
        // decimal
        Intbox decimal = new Intbox(var.getDecimal());
        decimal.setHflex("1");
        decimal.setParent(row);
        // value
        Textbox value = new Textbox(var.getValue());
        value.setHflex("1");
        value.setParent(row);
        // desp
        Textbox desp = new Textbox(var.getDesp());
        desp.setHflex("1");
        desp.setParent(row);
        // scope
        Combobox scope = WebUtils.createScopeTypeBox();
        scope.setValue(var.getScope().name());
        scope.setHflex("1");
        scope.setParent(row);
        // share
        Combobox share = WebUtils.createShareTypeBox();
        share.setHflex("1");
        share.setSelectedIndex(var.getShareModel());
        share.setParent(row);
        // acc
        Textbox acc = new Textbox(var.getAcc());
        acc.setHflex("1");
        acc.setParent(row);
        // button
        A btn = new A();
        btn.setTooltiptext(Labels.getLabel("button.delete"));
        btn.setIconSclass("z-icon-times");
        btn.setParent(row);
        row.setParent(variables.getRows());
        new VariableObject(name, type, length, decimal, value, desp, scope,
                share, acc, btn);
    }

    /**
     * 重绘源码
     */
    protected void refreshSource() {
        if (tabbox.getSelectedIndex() == 2)
            super.refreshSource();
    }

    @Override
    protected boolean validate() {
        if (Strings.isBlank(entity.getName())) {
            WebUtils.notEmpty(Labels.getLabel("entity.name"));
            return false;
        }
        if (Strings.isBlank(entity.getRefId())) {
            WebUtils.notEmpty(Labels.getLabel("entity.task.ref"));
            return false;
        }
        if (entity.getOnInit() != null) {
            boolean notId = Strings.isBlank(entity.getOnInit().getId());
            if (notId && Strings.isBlank(entity.getOnInit().getContent()))
                entity.setOnInit(null);
            else if (!notId)
                entity.getOnInit().setContent(null);
        }
        if (entity.getOnClose() != null) {
            boolean notId = Strings.isBlank(entity.getOnClose().getId());
            if (notId && Strings.isBlank(entity.getOnClose().getContent()))
                entity.setOnClose(null);
            else if (!notId)
                entity.getOnClose().setContent(null);
        }
        if (entity.getOnPreCommit() != null) {
            boolean notId = Strings.isBlank(entity.getOnPreCommit().getId());
            if (notId && Strings.isBlank(entity.getOnPreCommit().getContent()))
                entity.setOnPreCommit(null);
            else if (!notId)
                entity.getOnPreCommit().setContent(null);
        }
        if (entity.getOnPreCommitRollback() != null) {
            boolean notId = Strings.isBlank(entity.getOnPreCommitRollback()
                    .getId());
            if (notId
                    && Strings.isBlank(entity.getOnPreCommitRollback()
                    .getContent()))
                entity.setOnPreCommitRollback(null);
            else if (!notId)
                entity.getOnPreCommitRollback().setContent(null);
        }
        if (entity.getOnBeforeCommit() != null) {
            boolean notId = Strings.isBlank(entity.getOnBeforeCommit().getId());
            if (notId
                    && Strings.isBlank(entity.getOnBeforeCommit().getContent()))
                entity.setOnBeforeCommit(null);
            else if (!notId)
                entity.getOnBeforeCommit().setContent(null);
        }
        if (entity.getOnAfterCommit() != null) {
            boolean notId = Strings.isBlank(entity.getOnAfterCommit().getId());
            if (notId
                    && Strings.isBlank(entity.getOnAfterCommit().getContent()))
                entity.setOnAfterCommit(null);
            else if (!notId)
                entity.getOnAfterCommit().setContent(null);
        }
        if (entity.getOnRollback() != null) {
            boolean notId = Strings.isBlank(entity.getOnRollback().getId());
            if (notId && Strings.isBlank(entity.getOnRollback().getContent()))
                entity.setOnRollback(null);
            else if (!notId)
                entity.getOnRollback().setContent(null);
        }
        if (entity.getOnCommitted() != null) {
            boolean notId = Strings.isBlank(entity.getOnCommitted().getId());
            if (notId && Strings.isBlank(entity.getOnCommitted().getContent()))
                entity.setOnCommitted(null);
            else if (!notId)
                entity.getOnCommitted().setContent(null);
        }
        if (entity.getOnCommittedRollback() != null) {
            boolean notId = Strings.isBlank(entity.getOnCommittedRollback()
                    .getId());
            if (notId
                    && Strings.isBlank(entity.getOnCommittedRollback()
                    .getContent()))
                entity.setOnCommittedRollback(null);
            else if (!notId)
                entity.getOnCommittedRollback().setContent(null);
        }
        if (entity.getVariables() != null) {
            // 清除字称为空的变量
            Iterator<Variable> itr = entity.getVariables().iterator();
            while (itr.hasNext()) {
                Variable var = itr.next();
                if (Strings.isBlank(var.getName()))
                    itr.remove();
            }
            if (entity.getVariables().isEmpty())
                entity.setVariables(null);
        }
        if (entity.getDecision() != null) {
            if (entity.getDecision().getTransitions() == null
                    || entity.getDecision().getTransitions().isEmpty())
                entity.setDecision(null);
            else {
                Iterator<TransitionBean> itr = entity.getDecision()
                        .getTransitions().iterator();
                while (itr.hasNext()) {
                    TransitionBean bean = itr.next();
                    if (Strings.isBlank(bean.getName())) {
                        WebUtils.notEmpty(Labels
                                .getLabel("entity.task.decision.name"));
                        return false;
                    }
                    if (Strings.isBlank(bean.getTo())) {
                        WebUtils.notEmpty(Labels
                                .getLabel("entity.task.decision.to"));
                        return false;
                    }
                }
            }
        }
        return true;
    }

    /*
     * 事件分发
     */
    @Override
    protected void dispatch(final Event evt) {
        // 添加变量
        if (evt.getName().equals(Events.ON_SELECT)
                && evt.getTarget() instanceof Tab) {
            if (tabbox.getSelectedIndex() == 0) {
                redraw();
            } else if (tabbox.getSelectedIndex() == 2) {
                refreshSource();
            }
        } else if ("entityTask_column_variable_addVariable".equals(evt.getTarget().getId())) {
            Variable var = new Variable();
            var.setType(FieldType.VARCHAR);
            var.setScope(ScopeType.PUBLIC);
            if (entity.getVariables() == null)
                entity.setVariables(new ArrayList<Variable>());
            entity.getVariables().add(var);
            createVariable(var);
            setDirty();
        } else if ("entityTask_tabbox_flow_addTransition".equals(evt.getTarget().getId())) {// 添加分支
            TransitionBean bean = new TransitionBean();
            if (entity.getDecision() == null)
                entity.setDecision(new DecisionBean());
            if (entity.getDecision().getTransitions() == null)
                entity.getDecision().setTransitions(
                        new ArrayList<TransitionBean>());
            entity.getDecision().getTransitions().add(bean);
            createTransition(bean).setOpen(true);
            setDirty();
        } else if (Events.ON_CHANGE.equals(evt.getName())
                || Events.ON_CHECK.equals(evt.getName())) {// 变更数据
            Component c = evt.getTarget();
            if (c == entityName) {
                entity.setName(entityName.getValue());
                redraw();
            } else if (c == entityDesp) {
                entity.setDescription(entityDesp.getValue());
                redraw();
            } else if (c == entityRef) {
                entity.setRefId(entityRef.getValue());
                redraw();
            } else if (c == entityTable) {
                entity.setTable(entityTable.getValue());
                redraw();
            } else if (c == entityInherit) {
                entity.setInheritId(entityInherit.getValue());
                redraw();
            } else if (c == entityIcon)
                entity.setImage(entityIcon.getValue());
            else if (c == entityCode)
                entity.setProcessCode((String) entityCode.getSelectedItem()
                        .getValue());
            else if (c == entityType)
                entity.setExecuteType(entityType.getSelectedIndex());
            else if (c == entityUpdateable)
                entity.setUpdatable(entityUpdateable.isChecked());
            else if (c == entityVisible)
                entity.setVisible(entityVisible.isChecked());
            else if (c == anonymousCombobox)
                entity.setAccessType(anonymousCombobox.getSelectedIndex());
            else if(c == mainTaskSwitch) {
                if (mainTaskSwitch.isChecked() == false) {
                    entity.setSubType(null);
                }
                else {
                    entity.setSubType(SubType.Main.getName());
                }
                typeLinkVo.setRoot(entityVisible.isChecked() == false? TypeLinkVo.NODEENTITYID: TypeLinkVo.ROOTENTITYID);
                StudioApp.execute(new UpdateTaskLinkCmd(typeLinkVo));
                workbench.getEntityBar().refreshModule();
                workbench.getEntityWindowBar().refreshModule();
            }
            else if (c == decision) {
                String value = (String) decision.getValue();
                if (Strings.isBlank(value)) {
                    if (entity.getDecision() != null) {
                        if (entity.getDecision().getTransitions() == null
                                || entity.getDecision().getTransitions()
                                .isEmpty()) {
                            entity.setDecision(null);
                        } else
                            entity.getDecision().setExpr("");
                    }
                } else {
                    if (entity.getDecision() == null)
                        entity.setDecision(new DecisionBean());
                    entity.getDecision().setExpr(value);
                }

            } else if (c == onInit) {
                if (Strings.isBlank(onInit.getValue())) {
                    if (entity.getOnInit() != null) {
                        if (Strings.isBlank(entity.getOnInit().getContent())) {
                            entity.setOnInit(null);
                        } else
                            entity.getOnInit().setId(null);
                    }
                } else {
                    if (entity.getOnInit() == null)
                        entity.setOnInit(new EventLogic());
                    entity.getOnInit().setId(onInit.getValue());
                }
                redraw();
            } else if (c == onClose) {
                if (Strings.isBlank(onClose.getValue())) {
                    if (entity.getOnClose() != null) {
                        if (Strings.isBlank(entity.getOnClose().getContent())) {
                            entity.setOnClose(null);
                        } else
                            entity.getOnClose().setId(null);
                    }
                } else {
                    if (entity.getOnClose() == null)
                        entity.setOnClose(new EventLogic());
                    entity.getOnClose().setId(onClose.getValue());
                }
                redraw();
            } else if (c == onPreCommit) {
                if (Strings.isBlank(onPreCommit.getValue())) {
                    if (entity.getOnPreCommit() != null) {
                        if (Strings.isBlank(entity.getOnPreCommit()
                                .getContent())) {
                            entity.setOnPreCommit(null);
                        } else
                            entity.getOnPreCommit().setId(null);
                    }
                } else {
                    if (entity.getOnPreCommit() == null)
                        entity.setOnPreCommit(new EventLogic());
                    entity.getOnPreCommit().setId(onPreCommit.getValue());
                }
                redraw();
            } else if (c == onPreCommitRollback) {
                if (Strings.isBlank(onPreCommitRollback.getValue())) {
                    if (entity.getOnPreCommitRollback() != null) {
                        if (Strings.isBlank(entity.getOnPreCommitRollback()
                                .getContent())) {
                            entity.setOnPreCommitRollback(null);
                        } else
                            entity.getOnPreCommitRollback().setId(null);
                    }
                } else {
                    if (entity.getOnPreCommitRollback() == null)
                        entity.setOnPreCommitRollback(new EventLogic());
                    entity.getOnPreCommitRollback().setId(
                            onPreCommitRollback.getValue());
                }
                redraw();
            } else if (c == onBeforeCommit) {
                if (Strings.isBlank(onBeforeCommit.getValue())) {
                    if (entity.getOnBeforeCommit() != null) {
                        if (Strings.isBlank(entity.getOnBeforeCommit()
                                .getContent())) {
                            entity.setOnBeforeCommit(null);
                        } else
                            entity.getOnBeforeCommit().setId(null);
                    }
                } else {
                    if (entity.getOnBeforeCommit() == null)
                        entity.setOnBeforeCommit(new EventLogic());
                    entity.getOnBeforeCommit().setId(onBeforeCommit.getValue());
                }
                redraw();
            } else if (c == onAfterCommit) {
                if (Strings.isBlank(onAfterCommit.getValue())) {
                    if (entity.getOnAfterCommit() != null) {
                        if (Strings.isBlank(entity.getOnAfterCommit()
                                .getContent())) {
                            entity.setOnAfterCommit(null);
                        } else
                            entity.getOnAfterCommit().setId(null);
                    }
                } else {
                    if (entity.getOnAfterCommit() == null)
                        entity.setOnAfterCommit(new EventLogic());
                    entity.getOnAfterCommit().setId(onAfterCommit.getValue());
                }
                redraw();
            } else if (c == onRollback) {
                if (Strings.isBlank(onRollback.getValue())) {
                    if (entity.getOnRollback() != null) {
                        if (Strings
                                .isBlank(entity.getOnRollback().getContent())) {
                            entity.setOnRollback(null);
                        } else
                            entity.getOnRollback().setId(null);
                    }
                } else {
                    if (entity.getOnRollback() == null)
                        entity.setOnRollback(new EventLogic());
                    entity.getOnRollback().setId(onRollback.getValue());
                }
                redraw();
            } else if (c == onCommitted) {
                if (Strings.isBlank(onCommitted.getValue())) {
                    if (entity.getOnCommitted() != null) {
                        if (Strings.isBlank(entity.getOnCommitted()
                                .getContent())) {
                            entity.setOnCommitted(null);
                        } else
                            entity.getOnCommitted().setId(null);
                    }
                } else {
                    if (entity.getOnCommitted() == null)
                        entity.setOnCommitted(new EventLogic());
                    entity.getOnCommitted().setId(onCommitted.getValue());
                }
                redraw();
            } else if (c == onCommittedRollback) {
                if (Strings.isBlank(onCommittedRollback.getValue())) {
                    if (entity.getOnCommittedRollback() != null) {
                        if (Strings.isBlank(entity.getOnCommittedRollback()
                                .getContent())) {
                            entity.setOnCommittedRollback(null);
                        } else
                            entity.getOnCommittedRollback().setId(null);
                    }
                } else {
                    if (entity.getOnCommittedRollback() == null)
                        entity.setOnCommittedRollback(new EventLogic());
                    entity.getOnCommittedRollback().setId(
                            onCommittedRollback.getValue());
                }
                redraw();
            }
            setDirty();
        } else if (evt.getTarget() == accessChosenbox) {
            List<String> accessList = new ArrayList<>();
            for (Object obj:accessChosenbox.getSelectedObjects()){
                accessList.add(obj+"");
            }
            entity.setAccess(StringUtil.listToString(accessList, ","));
            setDirty();
        }
        /* else if (ecotree.equals(evt.getTarget())) {
            LinkVo selectedVo = ecotree.getSelectedItem().getValue();*/
        else if (ecoMind.equals(evt.getTarget()) && evt.getName().equals(Events.ON_DOUBLE_CLICK) && isShowCreate == false) {
            //isShowCreate = true;
            Node selectedNode = ecoMind.getSelectedNode();
            if (selectedNode != null) {
                LinkVo selectedVo = linkVoMap.get(selectedNode.getId());
                if (selectedVo != null) {
                    //双击
                    final LinkVo originalVo = new LinkVo(selectedVo.getEntityId(), selectedVo.getChildrenEntityId(),
                            selectedVo.getEntityName(), selectedVo.getEntityType(), selectedVo.getEntitySubType(),
                            selectedVo.getEntityDesp(), selectedVo.getCreateDate(), selectedVo.getUpdateDate(),
                            selectedVo.getCreateUser(), selectedVo.getUpdateUser(), selectedVo.getStatus());
                    //当出现关系表中显示为虚参数，但是却已经创建了，或者关系表中显示为实参数，却为创建，修正数据库关系
                    boolean isVirtual = (StudioApp.execute(evt.getTarget(),
                            new GetAndLockEntityCmd(selectedVo.getEntityId())) == null);
                    boolean isNeedRefresh = false;
                    if (LinkVo.ENTITYSTATUS.equals(selectedVo.getStatus()) && isVirtual == true) {
                        selectedVo.setStatus(LinkVo.VIRTUALSTATUS);
                        isNeedRefresh = true;
                    }
                    else if (LinkVo.VIRTUALSTATUS.equals(selectedVo.getStatus()) && isVirtual == false) {
                        selectedVo.setStatus(LinkVo.ENTITYSTATUS);
                        isNeedRefresh = true;
                    }
                    if (isNeedRefresh) {
                        StudioApp.execute(new UpdateLinkCmd(selectedVo));
                        voList = StudioApp.execute(new GetLinkCmd(entity.getId()));
                    }

                    if (LinkVo.ENTITYSTATUS.equals(selectedVo.getStatus()))
                    {
                        //打开参数
                        if (workbench.checkEditor(selectedVo.getEntityId()) == null) {
                            GetEntityVo ge = StudioApp.execute(evt.getTarget(),
                                    new GetAndLockEntityCmd(selectedVo.getEntityId()));
                            if (ge != null) {
                                char code = 'U';
                                if (!Strings.isBlank(ge.getLockUser())) {
                                    code = 'R';
                                    Messagebox.show(Labels.getLabel("enitiy.locked",
                                            new String[]{ge.getLockUser()}), Labels
                                                    .getLabel("message.title.error"),
                                            Messagebox.OK, Messagebox.INFORMATION);
                                }
                                workbench.createEditor(ge.getEntity(), code);
                            }
                        }
                    }
                    else if (LinkVo.VIRTUALSTATUS.equals(selectedVo.getStatus()))
                    {
                        //打开修改参数页面
                        isShowCreate = true;
                        workbench.getShortcutKeyBar().setDisabled("shortcutKey_div_create",true);
                        new CreateAction(workbench, selectedVo, new CreateAction.OnSuccessListener(){
                            @Override
                            public void getEntity(LinkVo linkVo) {
                                //为虚参数修改
                                CheckLinkCmd.CheckResultStatus resultStatus = StudioApp.execute(
                                        new CheckLinkCmd(originalVo, voList));
                                if (resultStatus == CheckLinkCmd.CheckResultStatus.CHECK_SUCCESS) {
                                    StudioApp.execute(new UpdateLinkCmd(linkVo));
                                    voList = StudioApp.execute(new GetLinkCmd(entity.getId()));
                                    redraw();
                                } else
                                {
                                    showError(resultStatus);
                                }
                            }

                            @Override
                            public void saveEntity(BaseEntity updateEntity) {
                                //添加实体参数
                                CheckLinkCmd.CheckResultStatus resultStatus = StudioApp.execute(
                                        new CheckLinkCmd(originalVo, voList));
                                if (resultStatus == CheckLinkCmd.CheckResultStatus.CHECK_SUCCESS) {
                                    LinkVo updateVo = new LinkVo(updateEntity.getId(), null, updateEntity.getName(),
                                            updateEntity.getType(), updateEntity.getSubType(), updateEntity.getDescription(), null,
                                            null, null, null, LinkVo.ENTITYSTATUS);
                                    StudioApp.execute(new UpdateLinkCmd(updateVo));
                                    voList = StudioApp.execute(new GetLinkCmd(entity.getId()));
                                    //redraw();
                                } else
                                {
                                    showError(resultStatus);
                                }
                            }

                            @Override
                            public void closeWindow() {
                                isShowCreate = false;
                                workbench.getShortcutKeyBar().setDisabled("shortcutKey_div_create",false);
                            }
                        }).on();
                    }
                }
            }
        } else if("entityTask_menuitem_appendVirtual".equals(evt.getTarget().getId())) {
            relationMenupopup.close();
            final LinkVo selectedVo = linkVoMap.get(ecoMind.getSelectedNode().getId());
            if (EntityType.TASK.getName().equals(selectedVo.getEntityType()) && selectedVo.equals(voList.get(0)) == false) {
                WebUtils.showInfo(Labels.getLabel("entity.task.taskAddError"));
                return;
            }
            if (selectedVo.isCanAdd() == false)
                return;
            String selector = new StringBuilder().append(EntityType.BATCH.getName())
                    .append(",").append(EntityType.BPM.getName()).append(",")
                    .append(EntityType.PAGE.getName()).append(",")
                    .append(EntityType.DATALIST.getName()).append(",")
                    .append(EntityType.REPORT.getName()).append(",")
                    .append(EntityType.TASK.getName()).append(",")
                    .append(EntityType.LOGIC.getName()).append(",")
                    .append(EntityType.RESOURCE.getName()).append(",")
                    .append(EntityType.TABLE.getName()).append(",")
                    .append(EntityType.API.getName()).toString();
            AbstractView.createEntityView(new ComponentEditorCallback(ecoMind, Labels.getLabel("navi.entity")),
                    selector, new EntityView.OnMsgListener() {
                @Override
                public void onMsg(String msg) {
                    BaseEntity entity = StudioApp.execute(ecoMind,new GetEntityCmd(msg));
                    LinkVo vo = new LinkVo(entity.getId(), null, entity.getName(),
                            entity.getType(), entity.getSubType(), entity.getDescription(), null,
                            null, null, null, LinkVo.ENTITYSTATUS);
                    addNewLink(vo, selectedVo);
                }
            }, null).doOverlapped();
        } else if("entityTask_menuitem_appendEntity".equals(evt.getTarget().getId())) {
            relationMenupopup.close();
            final LinkVo selectedVo = linkVoMap.get(ecoMind.getSelectedNode().getId());
            if (EntityType.TASK.getName().equals(selectedVo.getEntityType()) && selectedVo.equals(voList.get(0)) == false) {
                WebUtils.showInfo(Labels.getLabel("entity.task.taskAddError"));
                return;
            }
            if (selectedVo.isCanAdd() == false)
                return;
            new CreateAction(workbench, new CreateAction.OnSuccessListener(){
                @Override
                public void getEntity(LinkVo linkVo) {
                    //添加虚拟参数
                    addNewLink(linkVo, selectedVo);
                }

                @Override
                public void saveEntity(BaseEntity udapteEntity) {
                    //添加实体参数
                    LinkVo newVo = new LinkVo(udapteEntity.getId(), null, udapteEntity.getName(),
                            udapteEntity.getType(), udapteEntity.getSubType(), udapteEntity.getDescription(), null,
                            null, null, null, LinkVo.ENTITYSTATUS);
                    addNewLink(newVo, selectedVo);
                }

                @Override
                public void closeWindow() {
                    isShowCreate = false;
                }
            }).on();
        } else if("entityTask_menuitem_deleteVirtual".equals(evt.getTarget().getId())) {
            relationMenupopup.close();
            //删除关系
            LinkVo selectedVo = linkVoMap.get(ecoMind.getSelectedNode().getId());
            if (selectedVo.equals(voList.get(0))) {
                WebUtils.showInfo(Labels.getLabel("entity.task.isRootError"));
                return;
            }
            LinkVo parentVo = linkVoMap.get(ecoMind.getSelectedNode().getParent().getId());
            deleteLink(selectedVo, false, parentVo);
        } else if("entityTask_menuitem_deleteEntity".equals(evt.getTarget().getId())) {
            relationMenupopup.close();
            WebUtils.showConfirm(Labels.getLabel("entity.diagram.delete.current.entity"),
                    new EventListener<Event>() {
                        @Override
                        public void onEvent(Event event) throws Exception {
                            if (event.getName().equals(Messagebox.ON_YES)) {
                                //删除关系和参数
                                LinkVo selectedVo = linkVoMap.get(ecoMind.getSelectedNode().getId());
                                if (selectedVo.equals(voList.get(0))) {
                                    WebUtils.showInfo(Labels.getLabel("entity.task.isRootError"));
                                    return;
                                }
                                LinkVo parentVo = linkVoMap.get(ecoMind.getSelectedNode().getParent().getId());
                                deleteLink(selectedVo, true, parentVo);
                            }
                        }
                    });
        } else if("entityTask_button_HVSwitch".equals(evt.getTarget().getId())) {
            Button button = (Button) evt.getTarget();
            if ((Boolean) button.getAttribute("horizon") == true) {
                button.setAttribute("horizon" ,false);
                button.setImage("~./images/switch_vertical.png");
            } else {
                button.setAttribute("horizon" ,true);
                button.setImage("~./images/switch_horizon.png");
            }
        } else if("entityTask_button_ECSwitch".equals(evt.getTarget().getId())) {
            Button button = (Button) evt.getTarget();
            if ((Boolean) button.getAttribute("chinese") == true) {
                languageType = LanguageType.Language_En;
                button.setAttribute("chinese" ,false);
                button.setImage("~./images/language_en.png");
            } else {
                languageType = LanguageType.Language_Ch;
                button.setAttribute("chinese" ,true);
                button.setImage("~./images/language_ch.png");
            }
            voList = StudioApp.execute(new GetLinkCmd(entity.getId()));
            redraw();
        } else if("entityTask_button_autoAddLink".equals(evt.getTarget().getId())) {
            getAutoLinkList();
        } else {// 事件关联
            Component c = evt.getTarget();
            if (evt.getName().equals(Events.ON_OPEN)||evt instanceof KeyEvent) {// Bandbox
                if (c == entityIcon)
                    AbstractView.createIconView(
                            new BandboxCallback(this, (Bandbox) c), "*", evt.getTarget())
                            .doOverlapped();
                else {
                    String selector = EntityType.LOGIC.getName();
                    if (c == entityRef) {
                        /*selector = new StringBuilder().append(EntityType.BATCH.getName())
                                .append(",").append(EntityType.BPM.getName()).append(",")
                                .append(EntityType.PAGE.getName()).append(",")
                                .append(EntityType.DATALIST.getName()).append(",")
                                .append(EntityType.REPORT.getName()).toString();*/
                        selector = new StringBuilder().append(EntityType.BATCH.getName())
                                .append(",").append(EntityType.PAGE.getName()).toString();
                    } else if (c == entityInherit)
                        selector = EntityType.TASK.getName();
                    else if (c == entityTable)
                        selector = EntityType.TABLE.getName();
                    if (evt instanceof OpenEvent){
                        ((Bandbox) c).setValue(((OpenEvent)evt).getValue()+"");
                    }
                    AbstractView.createEntityView(
                            new BandboxCallback(this, (Bandbox) c), selector, c)
                            .doOverlapped();
                }
            } else {// 编辑按钮
                c = c.getPreviousSibling();
                if (c == entityRef) {
                    if (!Strings.isBlank(entityRef.getValue()))
                        openEditor(evt.getTarget(), entityRef.getValue());
                } else if (c == entityTable) {
                    if (!Strings.isBlank(entityTable.getValue()))
                        openEditor(evt.getTarget(), entityTable.getValue());
                } else if (c == onInit) {
                    if (Strings.isBlank(onInit.getValue())) {
                        if (entity.getOnInit() == null)
                            entity.setOnInit(new EventLogic());
                        AbstractView.createLogicView(
                                new EventLogicCallback(this, (Button) evt
                                        .getTarget(), entity.getOnInit(), entity.getTable(),
                                        "OnInit"), evt
                                        .getTarget()).doOverlapped();
                    } else {
                        openEditor(evt.getTarget(), onInit.getValue());
                    }
                } else if (c == onClose) {
                    if (Strings.isBlank(onClose.getValue())) {
                        if (entity.getOnClose() == null)
                            entity.setOnClose(new EventLogic());
                        Button btn = (Button) onClose.getNextSibling();
                        AbstractView.createLogicView(
                                new EventLogicCallback(this, (Button) evt
                                        .getTarget(), entity.getOnClose(), entity.getTable(),
                                        "OnClose"), btn).doOverlapped();
                    } else {
                        openEditor(evt.getTarget(), onClose.getValue());
                    }
                } else if (c == onPreCommit) {
                    if (Strings.isBlank(onPreCommit.getValue())) {
                        if (entity.getOnPreCommit() == null)
                            entity.setOnPreCommit(new EventLogic());
                        Button btn = (Button) onPreCommit.getNextSibling();
                        AbstractView.createLogicView(
                                new EventLogicCallback(this, (Button) evt
                                        .getTarget(), entity.getOnPreCommit(), entity.getTable(),
                                        "OnPreCommit"), btn).doOverlapped();
                    } else {
                        openEditor(evt.getTarget(), onPreCommit.getValue());
                    }
                } else if (c == onPreCommitRollback) {
                    if (Strings.isBlank(onPreCommitRollback.getValue())) {
                        if (entity.getOnPreCommitRollback() == null)
                            entity.setOnPreCommitRollback(new EventLogic());
                        Button btn = (Button) onPreCommitRollback.getNextSibling();
                        AbstractView.createLogicView(
                                new EventLogicCallback(this, (Button) evt
                                        .getTarget(), entity
                                        .getOnPreCommitRollback(), entity.getTable(),
                                        "OnPreCommitRollback"), btn).doOverlapped();
                    } else {
                        openEditor(evt.getTarget(),
                                onPreCommitRollback.getValue());
                    }
                } else if (c == onBeforeCommit) {
                    if (Strings.isBlank(onBeforeCommit.getValue())) {
                        if (entity.getOnBeforeCommit() == null)
                            entity.setOnBeforeCommit(new EventLogic());
                        Button btn = (Button) onBeforeCommit.getNextSibling();
                        AbstractView
                                .createLogicView(
                                        new EventLogicCallback(this,
                                                (Button) evt.getTarget(),
                                                entity.getOnBeforeCommit(), entity.getTable(),
                                                "OnBeforeCommit"), btn).doOverlapped();
                    } else {
                        openEditor(evt.getTarget(), onBeforeCommit.getValue());
                    }
                } else if (c == onAfterCommit) {
                    if (Strings.isBlank(onAfterCommit.getValue())) {
                        if (entity.getOnAfterCommit() == null)
                            entity.setOnAfterCommit(new EventLogic());
                        Button btn = (Button) onAfterCommit.getNextSibling();
                        AbstractView.createLogicView(
                                new EventLogicCallback(this, (Button) evt
                                        .getTarget(),
                                        entity.getOnAfterCommit(), entity.getTable(),
                                        "OnAfterCommit"), btn).doOverlapped();
                    } else {
                        openEditor(evt.getTarget(), onAfterCommit.getValue());
                    }
                } else if (c == onRollback) {
                    if (Strings.isBlank(onRollback.getValue())) {
                        if (entity.getOnRollback() == null)
                            entity.setOnRollback(new EventLogic());
                        Button btn = (Button) onRollback.getNextSibling();
                        AbstractView.createLogicView(
                                new EventLogicCallback(this, (Button) evt
                                        .getTarget(), entity.getOnRollback(), entity.getTable(),
                                        "OnRollback"), btn).doOverlapped();
                    } else {
                        openEditor(evt.getTarget(), onRollback.getValue());
                    }
                } else if (c == onCommitted) {
                    if (Strings.isBlank(onCommitted.getValue())) {
                        if (entity.getOnCommitted() == null)
                            entity.setOnCommitted(new EventLogic());
                        Button btn = (Button) onCommitted.getNextSibling();
                        AbstractView.createLogicView(
                                new EventLogicCallback(this, (Button) evt
                                        .getTarget(), entity.getOnCommitted(), entity.getTable(),
                                        "OnCommitted"), btn).doOverlapped();
                    } else {
                        openEditor(evt.getTarget(), onCommitted.getValue());
                    }
                } else if (c == onCommittedRollback) {
                    if (Strings.isBlank(onCommittedRollback.getValue())) {
                        if (entity.getOnCommittedRollback() == null)
                            entity.setOnCommittedRollback(new EventLogic());
                        Button btn = (Button) onCommittedRollback.getNextSibling();
                        AbstractView.createLogicView(
                                new EventLogicCallback(this, (Button) evt
                                        .getTarget(), entity
                                        .getOnCommittedRollback(), entity.getTable(),
                                        "OnCommittedRollback"), btn).doOverlapped();
                    } else {
                        openEditor(evt.getTarget(),
                                onCommittedRollback.getValue());
                    }
                }
            }
        }
    }
    //错误提示内容
    private void showError(CheckLinkCmd.CheckResultStatus status) {
        Messagebox.show(StudioUtil.getLinkErrorWithCode(status), Labels
                        .getLabel("message.title.error"),
                Messagebox.OK, Messagebox.INFORMATION);
    }
    @Override
    protected void redraw() {
        if (tabbox.getSelectedIndex() == 0) {
            if (ecoMind.root() != null) {
                ecoMind.root().clear();
            }
            linkVoMap = new HashMap<>();
            allTreeChildren(null, voList, true);
            ecoMind.reload();
        }
    }
    private void allTreeChildren(Node children, List<LinkVo> list, boolean isRoot) {
        for (LinkVo vo : list) {
            String id = StringUtil.getShortUUID();
            Node node = new Node(id);
            node.setBackgroundColor(getColorWithEntityTypeInTask(vo.getEntityType(),
                    vo.getEntitySubType()));
            node.setFontSize(15);
            node.setExpanded(true);
            linkVoMap.put(id, vo);
            String nameStr = null;
            if (languageType == LanguageType.Language_En) {
                String typeStr = StudioUtil.getStringWithEntityTypeInTask(vo.getEntityType(),
                        vo.getEntitySubType());
                nameStr = typeStr + ":" + vo.getEntityId();
            } else {
                String typeStr = StudioUtil.getSringWithEntityType(vo.getEntityType(),
                        vo.getEntitySubType());
                nameStr = typeStr + ":" + vo.getEntityName();
            }
            node.setTopic(StringUtil.truncatesLastLine(nameStr, 15));
            Node rootNode = null;
            if (isRoot == true) {
                rootNode = ecoMind.root(id, StringUtil.truncatesLastLine(nameStr, 15));
                rootNode.setBackgroundColor("#ee7470");
            }
            else
                children.appendChild(node);

            if (null != vo.getChildrenList() && vo.getChildrenList().size() != 0) {
                if (isRoot == true)
                    allTreeChildren(rootNode, vo.getChildrenList(), false);
                else
                    allTreeChildren(node, vo.getChildrenList(), false);
            }
            if (isRoot == false) {
                ecoMind.addEventListener(Events.ON_DOUBLE_CLICK,this);
            }
        }
    }

    private String getColorWithEntityTypeInTask(String entityType, String entitySubType) {
        String color = null;
        if (EntityType.TASK.getName().equals(entityType)) {
            color = "#ee7470";
        } else if (EntityType.PAGE.getName().equals(entityType)) {
            color = "#f6be42";
        } else if (EntityType.TABLE.getName().equals(entityType)) {
            color = "#72cac3";
        } else if (EntityType.DATALIST.getName().equals(entityType)) {
            color = "#f0916a";
        } else if (EntityType.LOGIC.getName().equals(entityType)) {
            color = "#4c196a";
        } else if (EntityType.API.getName().equals(entityType)) {
            color = "#74bfe7";
        } else if (EntityType.BATCH.getName().equals(entityType)) {
            color = "#e48b33";
        } else if (EntityType.BPM.getName().equals(entityType)) {
            color = "#5bbb61";
        } else if (EntityType.REPORT.getName().equals(entityType)) {
            color = "#c72d68";
        } else if (EntityType.RESOURCE.getName().equals(entityType)) {
            color = "#16593F";
        }
        return color;
    }

    //添加节点到数据库，重新获取数据库
    private void addNewLink(LinkVo vo, LinkVo parentVo)
    {
        CheckLinkCmd.CheckResultStatus resultStatus = checkAddNewLink(vo, parentVo);
        if (resultStatus != CheckLinkCmd.CheckResultStatus.CHECK_SUCCESS)
            showError(resultStatus);
        else {
            redraw();
            workbench.getEntityBar().refreshAll();
            workbench.getEntityWindowBar().refreshAll();
        }
    }
    private CheckLinkCmd.CheckResultStatus checkAddNewLink(LinkVo vo, LinkVo parentVo)
    {
        if (null != vo)
        {
            CheckLinkCmd.CheckResultStatus resultStatus = StudioApp.execute(
                    new CheckLinkCmd(parentVo, entity.getId(), voList, vo));
            List<String> childrenList = new ArrayList<>();
            if (Strings.isBlank(parentVo.getChildrenEntityId()) == false)
                childrenList = Arrays.asList(parentVo.getChildrenEntityId().split(","));
            if (resultStatus == CheckLinkCmd.CheckResultStatus.CHECK_SUCCESS)
            {
                if (childrenList.contains(vo.getEntityId())) {
                    return CheckLinkCmd.CheckResultStatus.CHECK_ERROR_DOUBLE;
                } else {
                    StudioApp.execute(new AddLinkCmd(vo));
                    if (EntityType.TASK.getName().equals(vo.getEntityType())) {
                        boolean isMain = SubType.Main.getName().equals(vo.getEntitySubType());
                        StudioApp.execute(new AddTaskLinkCmd(vo.getEntityId(), null, isMain));

                        String childrenLineStr = StringUtil.addStringToListString(typeLinkVo.getChildrenEntityId(),
                                ",", vo.getEntityId());
                        typeLinkVo.setChildrenEntityId(childrenLineStr);
                        StudioApp.execute(new UpdateTaskLinkCmd(typeLinkVo));
                    }
                    String childrenStr = StringUtil.addStringToListString(parentVo.getChildrenEntityId(),
                            ",", vo.getEntityId());
                    parentVo.setChildrenEntityId(childrenStr);
                    StudioApp.execute(new UpdateLinkCmd(parentVo));

                    voList = StudioApp.execute(new GetLinkCmd(entity.getId()));
                    typeLinkVo = StudioApp.execute(new GetTaskLinkCmd(typeLinkVo)).get(0);
                }
            }
            return resultStatus;
        } else
            return CheckLinkCmd.CheckResultStatus.CHECK_ERROR_NO_EXIT;
    }
    //删除节点，先删除页面数据，要删除参数再删除参数，关系数据库
    public void deleteLink(LinkVo deleteVo, boolean deleteEntity, LinkVo parentVo)
    {
        if (deleteEntity == true && null != deleteVo) {
            //删除参数
            setDeleteEntityData(deleteVo);
            //删除关系
            StudioApp.execute(new DeleteLinkCmd(deleteVo));
            StudioApp.execute(new DeleteTaskLinkCmd(new TypeLinkVo(deleteVo.getEntityId(), null, null)));
            //更新跟删除有关的关系
            List<LinkVo> updateVos = StudioApp.execute(new GetChildrenLinkCmd(deleteVo.getEntityId()));
            if (updateVos != null && updateVos.size() > 0) {
                for (LinkVo updateVo: updateVos) {
                    String childrenStr = StringUtil.removeStringToListString(updateVo.getChildrenEntityId(),
                            ",", deleteVo.getEntityId());
                    updateVo.setChildrenEntityId(childrenStr);
                }
                StudioApp.execute(new UpdateLinkListCmd(updateVos, deleteVo.getEntityId()));
            }
            List<TypeLinkVo> updateLinkVos = StudioApp.execute(new GetChildrenTaskLinkCmd(deleteVo.getEntityId()));
            if (updateLinkVos != null && updateLinkVos.size() > 0) {
                for (TypeLinkVo updateVo: updateLinkVos) {
                    String childrenStr = StringUtil.removeStringToListString(updateVo.getChildrenEntityId(),
                            ",", deleteVo.getEntityId());
                    updateVo.setChildrenEntityId(childrenStr);
                }
                StudioApp.execute(new UpdateTaskLinkListCmd(updateLinkVos, deleteVo.getEntityId()));
            }
        }
        if (deleteEntity == false &&  null != deleteVo && null != parentVo) {
            String childrenStr = StringUtil.removeStringToListString(parentVo.getChildrenEntityId(),
                    ",", deleteVo.getEntityId());
            parentVo.setChildrenEntityId(childrenStr);
            StudioApp.execute(new UpdateLinkCmd(parentVo));
        }
        voList = StudioApp.execute(new GetLinkCmd(entity.getId()));
        workbench.getEntityBar().refreshAll();
        workbench.getEntityWindowBar().refreshAll();
        updateTaskLink();
        redraw();
    }
    private void updateTaskLink() {
        List<String> childrenIdList = new ArrayList<>();
        childrenIdList = childrenLine(voList, childrenIdList);
        String childrenStr = StringUtil.listToString(childrenIdList, ",");
        typeLinkVo.setChildrenEntityId(childrenStr);
        StudioApp.execute(new UpdateTaskLinkCmd(typeLinkVo));
        workbench.getEntityBar().refreshAll();
        workbench.getEntityWindowBar().refreshAll();
    }
    private List<String> childrenLine(List<LinkVo> voList, List<String> childrenIdList) {
        for (LinkVo linkVo: voList) {
            if (EntityType.TASK.getName().equals(linkVo.getEntityType()) &&
                    linkVo.getEntityId().equals(entity.getId()) == false) {
                childrenIdList.add(linkVo.getEntityId());
            }
            if (linkVo.getChildrenList().size() > 0)
                childrenLine(linkVo.getChildrenList(), childrenIdList);
        }
        return childrenIdList;
    }
    //移动节点
    private void moveLink(Event event)
    {
        DropEvent de = (DropEvent) event;
        if (de.getDragged() instanceof Orgitem) {
            Orgitem moveItem = (Orgitem) de.getDragged();
            LinkVo moveVo = moveItem.getValue();
            Orgitem parentItem = moveItem.getParentItem();
            LinkVo parentVo = parentItem.getValue();
            Orgitem toMoveItem = (Orgitem) de.getTarget();
            LinkVo toMoveVo = toMoveItem.getValue();
            //若移动末终节点为task，则不能移动
            if (toMoveVo.getEntityId().equals(voList.get(0).getEntityId()) == false
                    && EntityType.TASK.getName().equals(toMoveVo.getEntityType()) == true) {
                Messagebox.show(
                        Labels.getLabel("entity.diagram.error.taskAddEntity"));
                return;
            }
            //删除节点，并添加新节点
            CheckLinkCmd.CheckResultStatus resultStatus = StudioApp.execute(new CheckLinkCmd(moveVo, toMoveVo, parentVo, voList));
            if (resultStatus == CheckLinkCmd.CheckResultStatus.CHECK_SUCCESS)
            {
                String removeStr = StringUtil.removeStringToListString(parentVo.getChildrenEntityId(),
                        ",", moveVo.getEntityId());
                parentVo.setChildrenEntityId(removeStr);
                StudioApp.execute(new UpdateLinkCmd(parentVo));

                String addStr = StringUtil.addStringToListString(toMoveVo.getChildrenEntityId(),
                        ",", moveVo.getEntityId());
                toMoveVo.setChildrenEntityId(addStr);
                StudioApp.execute(new UpdateLinkCmd(toMoveVo));

                voList = StudioApp.execute(new GetLinkCmd(entity.getId()));
                updateTaskLink();
                redraw();
            }
            else
            {
                showError(resultStatus);
            }
        } else if (de.getDragged() instanceof Listitem) {
            Listitem moveItem = (Listitem) de.getDragged();
            EntityVo moveEntityVo  = moveItem.getValue();
            LinkVo moveLinkVo = new LinkVo(moveEntityVo.getId(), null, moveEntityVo.getName(), moveEntityVo.getType(),
                    moveEntityVo.getSubType(), moveEntityVo.getDesp(), null, null, null, null, "E");
            Orgitem toMoveItem = (Orgitem) de.getTarget();
            LinkVo toMoveVo = toMoveItem.getValue();
            addNewLink(moveLinkVo,toMoveVo);
        }
    }
    //删除对象
    private void setDeleteEntityData(LinkVo deleteVo)
    {
        if (workbench.checkEditor(deleteVo.getEntityId()) == null) {
            GetEntityVo ge = StudioApp.execute(new GetAndLockEntityCmd(deleteVo.getEntityId()));
            if (ge != null) {
                if (!Strings.isBlank(ge.getLockUser())) {
                    Messagebox.show(Labels.getLabel("enitiy.locked",
                            new String[]{ge.getLockUser()}), Labels
                                    .getLabel("message.title.error"),
                            Messagebox.OK, Messagebox.INFORMATION);
                } else {
                    EntityInfo ei = new EntityInfo();
                    ei.setId(deleteVo.getEntityId());
                    ei.setStatus('D');
                    StudioApp.execute(new SaveCmd(ei));
                    workbench.getEntityBar().refreshModule();
                    workbench.getEntityWindowBar().refreshModule();
                    Editor editor = workbench.checkEditor(ei.getId());
                    if (editor != null && editor instanceof EntityEditor<?>)
                        ((EntityEditor<?>) editor).close();
                }
            }
        }
    }

    private void getAutoLinkList() {
        List<LinkVo> addLinkVoList = new ArrayList<>();
        //获取根关系
        List nextList = new ArrayList();
        nextList.add(entity);
        getLinkWithEntity(nextList, voList, addLinkVoList);
        System.out.println(addLinkVoList);
        for (int index = 0; index < addLinkVoList.size(); index++) {
            LinkVo addVo = addLinkVoList.get(index);
            //LinkVo parentVo = StudioApp.execute(ecoMind,new GetLinkCmd(addVo.getEntityId())).get(0);
            LinkVo parentVo = StudioApp.execute(ecoMind,new GetLinkCmd(addVo.getEntityId())).get(0);
            for (LinkVo entityVo :
                    addVo.getChildrenList()) {
                CheckLinkCmd.CheckResultStatus result = checkAddNewLink(entityVo, parentVo);
                /*if (result != CheckLinkCmd.CheckResultStatus.CHECK_SUCCESS)
                log.debugf("<addVo:"+entityVo.getEntityId()+">,<parentVo:"+parentVo.getEntityId()+">");*/
            }
        }

        redraw();
        workbench.getEntityBar().refreshAll();
        workbench.getEntityWindowBar().refreshAll();
    }

    private void getLinkWithEntity(List<BaseEntity> nextList, List<LinkVo> rootLinkVoList,
                                   List<LinkVo> linkVos) {
        GrammarUtil util = new GrammarUtil();
        List<List<String>> addEntityIdList = util.getNextLinks(nextList);
        List<BaseEntity> newNextList = new ArrayList<>();
        List<LinkVo> newRootLinkVoList = new ArrayList<>();
        for (int addEntityIdIndex = 0; addEntityIdIndex < addEntityIdList.size(); addEntityIdIndex++) {
            List<String> entityIdList = addEntityIdList.get(addEntityIdIndex);
            if (entityIdList.size() > 0) {
                LinkVo rootLinkVo = rootLinkVoList.get(addEntityIdIndex);
                List<BaseEntity> addBaseEntityList = StudioApp.execute(new GetBaseEntityListCmd(entityIdList));

                //新关系
                LinkVo addVo = new LinkVo();
                addVo.setEntityId(rootLinkVo.getEntityId());
                List<LinkVo> childrenList = new ArrayList<>();
                //与当前层关系比对，添加新关系
                for (BaseEntity baseEntity : addBaseEntityList) {
                    boolean isContain = false;
                    if (rootLinkVo.getChildrenList() != null) {
                        for (LinkVo linkVo : rootLinkVo.getChildrenList()) {
                            if (linkVo.getEntityId().equals(baseEntity.getId())) {
                                isContain = true;
                                //如果包含，添加当前关系到根关系
                                if (baseEntity.getType().equals(EntityType.TASK.getName()) == false)
                                    newRootLinkVoList.add((LinkVo) linkVo.clone());
                                break;
                            }
                        }
                    }
                    if (baseEntity.getId().equals(entity.getId()) == false
                            && rootLinkVo.getEntityId().equals(baseEntity.getId()) == false) {
                        LinkVo newRootVo = new LinkVo();
                        newRootVo.setEntityId(baseEntity.getId());
                        newRootVo.setEntityName(baseEntity.getName());
                        newRootVo.setEntityType(baseEntity.getType());
                        newRootVo.setEntitySubType(baseEntity.getSubType());
                        newRootVo.setEntityDesp(baseEntity.getDescription());
                        newRootVo.setStatus("E");
                        if (isContain == false) {
                            //如果不包含，则需要创建一个新的关系
                            childrenList.add(newRootVo);
                        }
                        //只针对页面，逻辑，列表进行下一层的搜索
                        if (baseEntity.getType().equals(EntityType.PAGE.getName()) ||
                                baseEntity.getType().equals(EntityType.LOGIC.getName())||
                                baseEntity.getType().equals(EntityType.DATALIST.getName())) {
                            newNextList.add(baseEntity);
                            newRootLinkVoList.add(newRootVo);
                        }
                    }
                }
                addVo.setChildrenList(childrenList);
                linkVos.add(addVo);
            }
        }
        if (newNextList.size() > 0)
            getLinkWithEntity(newNextList, newRootLinkVoList, linkVos);
    }
    private class VariableObject implements EventListener<Event> {
        private Textbox name;

        private Combobox type;

        private Intbox length;

        private Intbox decimal;

        private Textbox value;

        private Textbox desp;

        private Combobox scope;

        private Combobox share;

        private Textbox acc;

        public VariableObject(Textbox name, Combobox type, Intbox length,
                              Intbox decimal, Textbox value, Textbox desp, Combobox scope,
                              Combobox share, Textbox acc, A btn) {
            this.name = name;
            this.type = type;
            this.length = length;
            this.decimal = decimal;
            this.value = value;
            this.desp = desp;
            this.scope = scope;
            this.share = share;
            this.acc = acc;
            this.name.addEventListener(Events.ON_CHANGE, this);
            this.type.addEventListener(Events.ON_CHANGE, this);
            this.length.addEventListener(Events.ON_CHANGE, this);
            this.decimal.addEventListener(Events.ON_CHANGE, this);
            this.value.addEventListener(Events.ON_CHANGE, this);
            this.desp.addEventListener(Events.ON_CHANGE, this);
            this.scope.addEventListener(Events.ON_CHANGE, this);
            this.share.addEventListener(Events.ON_CHANGE, this);
            this.acc.addEventListener(Events.ON_CHANGE, this);
            btn.addEventListener(Events.ON_CLICK, this);
        }

        @Override
        public void onEvent(Event event) throws Exception {
            if (Events.ON_CHANGE.equals(event.getName())) {
                Row row = (Row) name.getParent();
                Variable var = row.getValue();
                Component c = event.getTarget();
                if (c == name)
                    var.setName(name.getValue());
                else if (c == type)
                    var.setType(FieldType.getType(type.getSelectedItem()
                            .getLabel()));
                else if (c == length)
                    var.setLength(length.getValue());
                else if (c == decimal)
                    var.setDecimal(decimal.getValue());
                else if (c == value)
                    var.setValue(value.getValue());
                else if (c == desp)
                    var.setDesp(desp.getValue());
                else if (c == scope)
                    var.setScope(ScopeType.getType(scope.getSelectedItem()
                            .getLabel()));
                else if (c == share)
                    var.setShareModel(share.getSelectedIndex());
                else if (c == acc)
                    var.setAcc(acc.getValue());
                setDirty();
            } else if (Events.ON_CLICK.equals(event.getName())) {
                WebUtils.showConfirm(Labels.getLabel("button.delete"), this);
            } else if (Events.ON_OK.equals(event.getName())) {
                Row row = (Row) name.getParent();
                Variable var = row.getValue();
                if (entity.getVariables().contains(var))
                    entity.getVariables().remove(var);
                else
                    logger.warn("Var:" + var.toString() + ";Variables:" + entity.getVariables().toString());
                row.detach();
                setDirty();
            }
        }

    }

    private class TransitionObject implements EventListener<Event> {

        private TransitionBean bean;

        private Textbox name;

        private Textbox dispName;

        private Textbox from;

        private Bandbox to;

        private Bandbox logic;

        public TransitionObject(TransitionBean bean, Textbox name,
                                Textbox dispName, Textbox from, Bandbox to, Bandbox logic) {
            this.bean = bean;
            this.name = name;
            this.dispName = dispName;
            this.from = from;
            this.to = to;
            this.logic = logic;
            this.name.addEventListener(Events.ON_CHANGE, this);
            this.name.getNextSibling().addEventListener(Events.ON_CLICK, this);
            this.dispName.addEventListener(Events.ON_CHANGE, this);
            this.from.addEventListener(Events.ON_CHANGE, this);
            this.to.addEventListener(Events.ON_CHANGE, this);
            this.to.addEventListener(Events.ON_OPEN, this);
            this.to.getNextSibling().addEventListener(Events.ON_CLICK, this);
            this.logic.addEventListener(Events.ON_CHANGE, this);
            this.logic.addEventListener(Events.ON_OPEN, this);
            this.logic.getNextSibling().addEventListener(Events.ON_CLICK, this);
        }

        @Override
        public void onEvent(final Event event) throws Exception {
            if (event.getName().equals(Events.ON_CHANGE)) {
                if (event.getTarget() == name) {
                    bean.setName(name.getValue());
                    redraw();
                } else if (event.getTarget() == dispName)
                    bean.setDisplayName(dispName.getValue());
                else if (event.getTarget() == from)
                    bean.setFrom(from.getValue());
                else if (event.getTarget() == to)
                    bean.setTo(to.getValue());
                else
                    bean.setLogicId(logic.getValue());
                setDirty();
            } else if (event.getName().equals(Events.ON_CLICK)) {
                Component c = event.getTarget().getPreviousSibling();
                if (c == name) {// 删除按钮
                    WebUtils.showConfirm(Labels.getLabel("button.delete"), this);
                } else if (c == to) {// to
                    if (!Strings.isBlank(bean.getTo())) {
                        openEditor(event.getTarget(), bean.getTo());
                    }
                } else {// logic
                    if (!Strings.isBlank(bean.getLogicId())) {
                        openEditor(event.getTarget(), bean.getLogicId());
                    } else {
                        AbstractView.createLogicView(
                                new TransitionEditorCallback(
                                        TaskEntityEditor.this, bean,
                                        (Button) event.getTarget(), entity.getTable()), event.getTarget()).doOverlapped();
                    }
                }
            } else if (event.getName().equals(Events.ON_OPEN)) {
                Component c = event.getTarget();
                if (c == to) {// to
                    AbstractView.createEntityView(
                            new BandboxCallback(TaskEntityEditor.this,
                                    (Bandbox) c), EntityType.TASK.getName(), to)
                            .doOverlapped();
                } else {// logic
                    AbstractView.createEntityView(
                            new BandboxCallback(TaskEntityEditor.this,
                                    (Bandbox) c), EntityType.LOGIC.getName(), logic)
                            .doOverlapped();
                }
            } else if (event.getName().equals(Events.ON_OK)) {// 删除
                name.getParent().getParent().detach();
                dispName.getParent().detach();
                from.getParent().detach();
                to.getParent().getParent().detach();
                logic.getParent().getParent().detach();
                entity.getDecision().getTransitions().remove(bean);
                setDirty();
                if (!Strings.isBlank(name.getValue()))
                    redraw();
            }
        }
    }
}
